#include <slothttpd/config/location/fcgi_location.hpp>
#include <slothttpd/stage/proxy_fcgi.hpp>
#include <slothttpd/config/server.hpp>

namespace slothttpd {
namespace config {

fcgi_location::fcgi_location(const boost::property_tree::ptree &node, server &s) :
    base_location(node, s)
{
    std::string name = node.get<std::string>("fcgi_name");
    
    for (auto &a : s.conf.fcgi_apps) {
        if (name == a->name) {
            app = a;
            break;
        }
    }
    
    fcgi_stdout_buffers.size = node.get<std::size_t>("fcgi_stdout_buffers.size");
    fcgi_stdout_buffers.nmax = node.get<std::size_t>("fcgi_stdout_buffers.nmax");
    fcgi_stderr_buffers.size = node.get<std::size_t>("fcgi_stdout_buffers.size");
    fcgi_stderr_buffers.nmax = node.get<std::size_t>("fcgi_stdout_buffers.nmax");
    fcgi_output_buffer_size  = node.get<std::size_t>("fcgi_output_buffer_size");
    
    for (auto &v : node.get_child("fcgi_params")) {
        fcgi_params.push_back(params_type(v.first.data(), v.second.data(), *this));
    }
}

void fcgi_location::apply(connection_ptr c)
{
    c->pool.construct<stage::proxy_fcgi>(c, *this);
}

fcgi_location::params_range_t fcgi_location::params_range() const
{
    return params_range_t(fcgi_params.begin(), fcgi_params.end());
}

fcgi_location::params_type::params_type(const std::string &n, const std::string &v, base_location &loc) :
    name(n),
    format_string(v),
    value_formatter(formatter(v, loc))
{
}

std::ostream &operator<<(std::ostream &os, const fcgi_location &loc)
{
    os << static_cast<const base_location&>(loc)
       << "    fcgi_stdout_buffers " << loc.fcgi_stdout_buffers << '\n'
       << "    fcgi_stderr_buffers " << loc.fcgi_stdout_buffers << '\n'
       << "    fcgi_output_buffer_size: " << loc.fcgi_output_buffer_size << '\n'
       << "    fcgi_params:\n";
    
    for (auto &p : loc.fcgi_params) {
        os << p;
    }
    
    return os;
}

std::ostream &operator<<(std::ostream &os, const fcgi_location::params_type &par)
{
    os << "    --- params ---\n"
       << "        name: " << par.name << ", format: " << par.format_string << '\n';
    
    return os;
}

}
}
